package com.demo.common.support.controller;

import com.demo.common.support.model.DataResponse;
import com.demo.common.support.builder.ResponseBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.Collection;

/**
 * <p>将数据实体序列化成json格式.返回前端.通过{@link DataResponse}组件序列化
 * 交互消息的返回信息封装.业务代码可直接调用方法返回.
 * @author molong
 * @since 2024/5/24
 */
public abstract class AbstractDataResponseController {

    /**
     * 日志对象
     */
    protected final Logger LOGGER = LoggerFactory.getLogger(this.getClass());

    /**
     * 返回成功操作,并携带一个数据
     *
     * @param data 返回数据
     * @return 交互实体
     */
    protected <T> DataResponse<T> succeed(T data) {
        return succeed(data, null);
    }

    /**
     * 返回成功操作,并携带一个数据
     *
     * @return 交互实体
     */
    protected <T> DataResponse<T> succeed() {
        return succeed(null, null);
    }

    /**
     * 返回成功操作,并携带一个封装成集合{@link Collection}的实体
     *
     * @param data 返回数据
     * @param <T>  返回参数类型
     * @return 交互实体
     */
    protected <T> DataResponse<T> succeed(Collection<T> data) {
        return succeed(data, null);
    }

    /**
     * 返回成功操作,并携带一个数据以及返回成功提示
     *
     * @param data    返回数据
     * @param message 返回成功消息
     * @return 交互实体
     */
    protected <T> DataResponse<T> succeed(T data, String message) {
        return ResponseBuilder.<T>start().data(data).succeed(message).build();
    }

    /**
     * 返回成功操作,并携带一个封装成集合{@link Collection}的实体以及成功消息提示
     *
     * @param data 返回数据
     * @param <T>  返回参数类型
     * @return 交互实体
     */
    protected <T> DataResponse<T> succeed(Collection<T> data, String message) {
        return ResponseBuilder.<T>start().data(data).succeed(message).build();
    }

    /**
     * 返回成功操作,携带自定义CODE,一个成功提示和结果代码
     *
     * @param message 返回成功消息提示
     * @return 交互实体
     */
    protected <T> DataResponse<T> succeed(T data, String message, int code) {
        return ResponseBuilder.<T>start().data(data).succeed(message, code).build();
    }

    /**
     * 返回成功操作,携带自定义CODE,一个成功提示和结果代码
     *
     * @param message 返回成功消息提示
     * @return 交互实体
     */
    protected <T> DataResponse<T> succeed(Collection<T> data, String message, int code) {
        return ResponseBuilder.<T>start().data(data).succeed(message, code).build();
    }


    /**
     * 返回成功操作,并携带一个成功提示
     *
     * @param message 返回成功消息提示
     * @return 交互实体
     */
    protected <T> DataResponse<T> succeed(String message) {
        return succeed(null, message);
    }

    /**
     * 返回成功操作,并携带一个成功提示和结果代码
     *
     * @param message 返回成功消息提示
     * @return 交互实体
     */
    protected <T> DataResponse<T> succeed(String message, int code) {
        return ResponseBuilder.<T>start().succeed(message, code).build();
    }


    /**
     * 返回一个成功操作,并协带一个数组数据
     *
     * @param data 返回数据
     * @param <T>  返回参数类型
     * @return 交互实体
     */
    protected <T> DataResponse<T> succeed(T[] data) {
        return succeed(Arrays.asList(data));
    }

    /**
     * 返回一个失败操作,并携带一个失败消息提示
     *
     * @param message 失败消息提示
     * @return 交互实体
     */
    protected <T> DataResponse<T> fail(String message) {
        return ResponseBuilder.<T>start().fail(message).build();
    }

    /**
     * 返回一个失败操作,并携带一个失败消息提示以及错误代码
     *
     * @param code 错误代码
     * @return 交互实体
     */
    protected <T> DataResponse<T> fail(int code) {
        return fail(null, null, code);
    }

    /**
     * 返回一个失败操作,并携带一个失败消息提示以及错误代码
     *
     * @param message 失败消息提示
     * @param code    错误代码
     * @return 交互实体
     */
    protected <T> DataResponse<T> fail(String message, int code) {
        return fail(null, message, code);
    }

    /**
     * 返回一个失败操作,并携带一个失败消息提示和数据以及错误代码
     *
     * @param message 失败消息提示
     * @param code    错误代码
     * @param data    返回数据
     * @return 交互实体
     */
    protected <T> DataResponse<T> fail(T data, String message, Integer code) {
        return ResponseBuilder.<T>start().data(data).fail(message, code).build();
    }

}